﻿/* **************************************************************************
 *
 * Copyright 2007-2010 Jeff Hardy
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * *************************************************************************/

using System;
using System.Collections.Generic;
using System.Net;

namespace NWSGI.HttpListener
{
    public class Request : IWsgiRequest
    {
        private HttpListenerRequest request;

        private string scriptName;
        private string pathInfo;

        public Request(HttpListenerRequest request)
        {
            this.request = request;
        }

        public string Method
        {
            get { return request.HttpMethod; }
        }

        public string ScriptName
        {
            get { ensureSplitPath(); return this.scriptName; }
        }

        public string PathInfo
        {
            get { ensureSplitPath(); return this.pathInfo; }
        }

        public string QueryString
        {
            get { return request.Url.Query; }
        }

        public string ContentType
        {
            get { return request.ContentType; }
        }

        public string ContentLength
        {
            get { return request.ContentLength64.ToString(); }
        }

        public string ServerName
        {
            get { return request.UserHostName.Split(':')[0]; }
        }

        public string ServerPort
        {
            get { return request.LocalEndPoint.Port.ToString(); }
        }

        public string ServerProtocol
        {
            get { return "1.1"; }
        }

        public IEnumerable<KeyValuePair<string, string>> Headers
        {
            get
            {
                foreach(string key in request.Headers)
                {
                    yield return new KeyValuePair<string, string>(key, request.Headers[key]);
                }
            }
        }

        public IEnumerable<KeyValuePair<string, string>> CgiServerVariables
        {
            get { return new List<KeyValuePair<string, string>>(); }
        }

        public Uri Url
        {
            get { return request.Url; }
        }

        public string RawUrl
        {
            get { return request.RawUrl; }
        }

        public System.IO.Stream InputStream
        {
            get { return request.InputStream; }
        }

        protected virtual void SplitPath(string path, out string scriptName, out string pathInfo)
        {
            var segments = path.Split('/');

            int fileSegment = -1;
            for(int i = 0; i < segments.Length; ++i)
            {
                var segment = segments[i];
                if(segment.Contains("."))
                {
                    fileSegment = i + 1;
                    break;
                }
            }

            if(fileSegment == -1)
            {
                scriptName = path;
                pathInfo = "";
            }
            else
            {
                scriptName = string.Join("/", segments, 0, fileSegment);
                pathInfo = string.Join("/", segments, fileSegment, segments.Length - fileSegment);
            }
        }

        private void ensureSplitPath()
        {
            if(this.scriptName == null || this.pathInfo == null)
            {
                this.SplitPath(request.Url.AbsolutePath, out this.scriptName, out this.pathInfo);
            }
        }
    }
}
